﻿using System;
//using System.Windows;
//using System.Windows.Controls;
//using System.Windows.Documents;
//using System.Windows.Ink;
//using System.Windows.Input;
//using System.Windows.Media;
//using System.Windows.Media.Animation;
//using System.Windows.Shapes;

namespace BankingDemo.Models
{
    public class RetirementPlan
    {
        #region Private Variables

            private int retirementAge;
            private int planToAge;
            private double annualEssentialExpenses;
            private double annualDiscretionaryExpenses;
            private double annualRetirementIncome;
            private double assets;
            private double homeEquity;
            private double liquidAssets;
            private double investments;
            private int investmentStyle;

            private int currentAge;
            private double currentAnnualIncome;

            private double contributionAmount;
            private double contributionPercent;

            private int planRange;

            private double[] essentialExpenses;
            private double[] discretionaryExpenses;
            private double[] income;

            private double maxDollarValue;
            private double totalIncomeAtRetirement;

        #endregion

        #region Constructors
            
            public RetirementPlan()
            {
                // Set current age and current annual income
                UserProfile user = new UserProfile();
                currentAnnualIncome = user.AnnualIncome;
                contributionAmount = currentAnnualIncome * contributionPercent;
                TimeSpan ts = DateTime.Today - user.DateOfBirth;
                currentAge = Convert.ToInt32(ts.TotalDays / 360);
            }

        #endregion

        #region Public Properties

            public int RetirementAge 
            { 
                get { return retirementAge; } 
                set 
                { 
                    retirementAge = value;
                    if (retirementAge > planToAge)
                    {
                        planToAge = retirementAge + 5;
                    }
                    planRange = planToAge - retirementAge;
                } 
            }
            public int PlanToAge
            {
                get { return planToAge; }
                set 
                { 
                    planToAge = value;
                    planRange = planToAge - retirementAge;
                }
            }
            public double AnnualEssentialExpenses
            {
                get { return annualEssentialExpenses; }
                set 
                { 
                    annualEssentialExpenses = value;
                }
            }
            public double AnnualDiscretionaryExpenses
            {
                get { return annualDiscretionaryExpenses; }
                set 
                { 
                    annualDiscretionaryExpenses = value;
                }
            }
            public double AnnualIncome
            {
                get { return annualRetirementIncome; }
                set 
                { 
                    annualRetirementIncome = value;                    
                }
            }
            public double HomeEquity
            {
                get { return homeEquity; }
                set
                {
                    homeEquity = value;
                    assets = homeEquity + liquidAssets + investments;
                }
            }
            public double LiquidAssets
            {
                get { return liquidAssets; }
                set
                {
                    liquidAssets = value;
                }
            }
            public double Investments
            {
                get { return investments; }
                set
                {
                    investments = value;
                }
            }
            public int InvestmentStyle
            {
                get { return investmentStyle; }
                set 
                { 
                    investmentStyle = value;
                }
            }

            public double[] EssentialExpensesArray
            {
                get { return essentialExpenses; }
                set { essentialExpenses = value; }
            }

            public double[] DiscretionaryExpensesArray
            {
                get { return discretionaryExpenses; }
                set { discretionaryExpenses = value; }
            }

            public double[] IncomeArray
            {
                get { return income; }
                set { income = value; }
            }

            public int PlanRange
            {
                get { return planRange; }
                set { planRange = value; }
            }

            public double MaxDollarValue
            {
                get { return maxDollarValue; }
                set { maxDollarValue = value; }
            }

            public double ContributionAmount
            {
                get { return contributionAmount; }
                set 
                {
                    contributionAmount = value;
                    contributionPercent = contributionAmount / currentAnnualIncome;
                }
            }

            public double ContributionPercent
            {
                get { return contributionPercent; }
                set 
                { 
                    contributionPercent = value;
                    contributionAmount = currentAnnualIncome * contributionPercent;
                }
            }

            public double TotalIncomeAtRetirement
            {
                get { return totalIncomeAtRetirement; }
                set { totalIncomeAtRetirement = value; }
            }

        #endregion

        #region Public Methods

            public void RecalculatePlan()
            {
                if (planRange < 0)
                {
                    return;
                }

                maxDollarValue = 100000;

                essentialExpenses = new double[planRange];
                discretionaryExpenses = new double[planRange];
                income = new double[planRange];

                // Calculate income saved and invested from current age to retirement age                
                double totalContributionGrowthAtRetirement = 0;
                double yearsUntilRetirement = retirementAge - currentAge;

                // Total contribution amount after growth
                for (int i = 0; i < yearsUntilRetirement; i++)
                {
                    totalContributionGrowthAtRetirement = totalContributionGrowthAtRetirement * (1 + investmentStyle / 100.00) + contributionAmount;
                }

                // Total income - total contribution amount + total contribution amount after growth at retirement
                totalIncomeAtRetirement = (currentAnnualIncome - contributionAmount) * yearsUntilRetirement + totalContributionGrowthAtRetirement;                

                // Calculate post retirement income and expenses
                for (int i = 0; i < planRange; i++)
                {
                    income[i] = totalIncomeAtRetirement + assets + (annualRetirementIncome * i);
                    essentialExpenses[i] = annualEssentialExpenses * i;
                    discretionaryExpenses[i] = (annualDiscretionaryExpenses + annualEssentialExpenses) * i;

                    // See if any of the numbers is larger than the max so far
                    if (income[i] > maxDollarValue)
                    {
                        maxDollarValue = income[i];
                    }
                    if(essentialExpenses[i] > maxDollarValue)
                    {
                        maxDollarValue = essentialExpenses[i];
                    }
                    if (discretionaryExpenses[i] > maxDollarValue)
                    {
                        maxDollarValue = discretionaryExpenses[i];
                    }
                }

                if (planChange != null)
                {
                    planChange(this, new EventArgs());
                }
            }

        #endregion

        #region Events

            public event EventHandler planChange;

        #endregion
    }
}
